#include <types.h>
#include <stdio.h>
#include <string.h>
#include <console.h>
#include <kdebug.h>
#include <picirq.h>
#include <trap.h>
#include <clock.h>
#include <intr.h>
#include <pmm.h>
#include <vmm.h>
#include <ramdisk.h>
#include <swap.h>
#include <proc.h>
#include <assert.h>
#include <atomic.h>

int kern_init(void) __attribute__((noreturn));

void dump_vector(uint32_t addr){
  int i;
  uint32_t *ptr = (uint32_t*)addr;
  for(i=0;i<16;i++)
    cprintf("%08x \n", *ptr++);

}


// Very important:
// At the boot, exceptions handlers have not been defined
// Copy the address of exceptions handlers (defined in vectors.S) to 0x24 
// (or Ox20 if we decide to change reset handler)
// XXX it works only when 0x0 is a sram/sdram


extern char __vector_table, __vector_table_end;
static inline void
exception_vector_init(void) {
  memcpy( (void*)0x0, (void*)&__vector_table,
      &__vector_table_end - &__vector_table);
}

int
kern_init(void) {
  extern char edata[], end[];
  memset(edata, 0, end - edata);

  exception_vector_init();

  dump_vector(0x0);

  cons_init();                // init the console

  const char *message = "(THU.CST) os is loading ...";
  cprintf("%s\n\n", message);
  cprintf("BUILD! "__TIMESTAMP__"\r\n");

  print_kerninfo();

  pmm_init();                 // init physical memory management

  dump_vector(0xffff0000);

  cprintf("pmm_init() done.\n");
  pic_init();                 // init interrupt controller
  cprintf("pic_init() done.\n");


  vmm_init();                 // init virtual memory management
  cprintf("vmm_init() done.\n");
  proc_init();                // init process table
  cprintf("proc_init() done.\n");

  ide_init();                 // init ide devices
  cprintf("ide_init() done.\n");
  swap_init();                // init swap
  cprintf("swap_init() done.\n");

  //clock_init();               // init clock interrupt
  //intr_enable();              // enable irq interrupt

  cpu_idle();                 // run idle process
}

